# latexTablePDF.R
# created 2014 March 14

# Takes LaTeX table code. Produces a PDF or a LaTeX file. 

latexTablePDF <- function(
  latexCommands,
  containerFilename  = NULL,
  outputFilenameStem = 'latexTable',
  
  continuedFloat     = FALSE,
  continuedFloatStar = FALSE,  
  firstPageEmpty     = TRUE,
  firstTableNumber   = 1,     # tables will be numbered consecutively, starting w/ this number
  wrapper            = TRUE,  # w/o wrapper, .tex file can't be PDF'd
  
  overwriteExisting  = FALSE,
  keepPDFFile        = TRUE,
  keepTexFile        = FALSE,
  openPDFOnExit      = TRUE) {
  

  # PRELIMINARIES AND ERROR-CHECKING
  oldWD <- getwd()
  on.exit(setwd(oldWD))
  if (! 'list' %in% class(latexCommands)) { 
    stop("latexCommands must be a list.")
  }
  if (file.exists(paste0(outputFilenameStem, '.pdf')) && overwriteExisting) {
    warning(paste0(outputFilenameStem, '.pdf will be overwritten.'))
  } else if (file.exists(paste0(outputFilenameStem, '.pdf')) && !overwriteExisting) {
    stop(paste0(outputFilenameStem, '.pdf already exists and overwriteExisting = FALSE.'))
  }
  if (file.exists(paste0(outputFilenameStem, '.tex')) && overwriteExisting && keepTexFile) {
    warning(paste0(outputFilenameStem, '.tex will be overwritten.'))
  } else if (file.exists(paste0(outputFilenameStem, '.tex')) && !overwriteExisting) {
    stop(paste0(outputFilenameStem, '.tex already exists and overwriteExisting = FALSE.'))
  }
  if (continuedFloat && continuedFloatStar) {
    stop('"continuedFloat" and "continuedFloatStar" cannot both be TRUE.')    
  }    
  if (!wrapper && keepPDFFile) {
    stop('if "wrapper" is FALSE, "keepPDFFile" must also be FALSE.')    
  }    
  
  
  # REMOVE PAGE NUMBER FROM FIRST PAGE
  # To remove the page number from the first page, 
  # \thispagestyle{empty} needs to go in the code block for the first 
  # LaTeX table.  
  if (firstPageEmpty) {
    table1 <- latexCommands[[1]]
    positionToInsertNewCommand <- which(grepl('newcommand', table1))
    table1 <- c(
      table1[1:positionToInsertNewCommand], 
      '  \\thispagestyle{empty}',
      table1[(positionToInsertNewCommand+1):length(table1)]
    )  
    latexCommands[[1]] <- table1
    rm(table1, positionToInsertNewCommand)
  }
  
  
  # CHANGE TABLE NUMBERING
  # We need to account for the weird LaTeX numbering scheme. For example, if 
  # firstTableNumber = 2, we insert \setcounter{table}{1} to get the first
  # table in the PDF file to be Table 2.   
  if (firstTableNumber != 1) {
    table1 <- latexCommands[[1]]
    positionToInsertNewCommand <- which(grepl('newcommand', table1))
    table1 <- c(
      table1[1:positionToInsertNewCommand], 
      paste0('  \\setcounter{table}{', firstTableNumber - 1, '}'),
      table1[(positionToInsertNewCommand+1):length(table1)]
    )  
    latexCommands[[1]] <- table1
    rm(table1, positionToInsertNewCommand)
  }
  
  # ADD \CONTINUEDFLOAT COMMANDS
  # E.g., for creating Figure "3a," Figure "3b"
  insertContinuedCommand <- function (x, star = FALSE) {
    lineToInsert <- if (star) '    \\ContinuedFloat*' else '    \\ContinuedFloat'    
    beginLine    <- which(grepl('\\\\begin\\{(table|figure)\\}', x))
    x            <- c(x[1:beginLine], lineToInsert, x[(beginLine+1):length(x)])
    x
  }
  if (continuedFloat || continuedFloatStar) {
    latexCommands <- lapply(
      X   = latexCommands, 
      FUN = function (x) insertContinuedCommand(x, star = continuedFloatStar))    
  }
  
  
  # CREATE THE ENTIRE LATEX DOCUMENT
  if (wrapper) {
    latexContainer <- readLines(containerFilename)
    lineToReplace  <- which(grepl('TABLE GOES HERE!', latexContainer))  
    newTable <- latexContainer[1:(lineToReplace)-1]
    for (i in 1:length(latexCommands)) {
      newTable <- c(newTable, paste0('% TABLE ', i), latexCommands[[i]], "", "")
    }
    newTable <- c(newTable, latexContainer[(lineToReplace+1):length(latexContainer)])
  } else {
    newTable <- ''
    for (i in 1:length(latexCommands)) {
      newTable <- c(newTable, paste0('% TABLE ', i), latexCommands[[i]], "", "")
    }    
  }
    
  # Check for \afterpage commands and eliminate them.  Apparently, in 
  # documents for which there is no content other than tables, 
  # \afterpage causes pdflatex to fail to compile to PDF.  [2014 03 15]  
  afterpageLines <- which(grepl('\\\\afterpage', newTable))
  if (any(afterpageLines)) {
    newTable <- newTable[-c(afterpageLines, afterpageLines+6)]
  }
  
  
  # CREATE FILES IN THE NEW TEMPORARY DIRECTORY
  tmpFilename <- tempfile(fileext = '.tex')  # includes path to tempdir()
  writeLines(newTable, tmpFilename)
  setwd(tempdir())
  if (wrapper) {
    shell(paste('pdflatex', shQuote(tmpFilename)), mustWork = TRUE)
  }

  
  
  
  # MOVE PDF OUT OF TEMPORARY DIRECTORY, THEN DELETE TEMP. DIRECTORY
  if (keepPDFFile) {
    file.copy(
      from      = sub("\\.tex", "\\.pdf", tmpFilename), 
      to        = paste0(oldWD, '/', outputFilenameStem, '.pdf'),
      overwrite = overwriteExisting)
  }
  if (keepTexFile) {
    file.copy(
      from      = tmpFilename, 
      to        = paste0(oldWD, '/', outputFilenameStem, '.tex'),
      overwrite = overwriteExisting)
  }

  
  # OPEN THE NEW PDF FILE (IF RUNNING WINDOWS)
  if (keepPDFFile && openPDFOnExit && Sys.info()['sysname'] == 'Windows') {
    PDFFullPath <- normalizePath(paste0(oldWD, '/', outputFilenameStem, '.pdf'))
    shell.exec(PDFFullPath)
  }
  
}
  